<script setup name="soundRecording">
import Recorder from "recorder-core";
import { useMyStore } from "../store/index";
import { soundJson } from "@/utils/index";
import lyks from "@/assets/lyks.png";
import lyz from "@/assets/lyz.png";
import stop from "@/assets/stop.png";
import sf from "@/assets/sf.png";
import "recorder-core/src/engine/mp3";
import "recorder-core/src/engine/mp3-engine";
import "recorder-core/src/extensions/waveview";
import { showToast } from "vant";
import { ref, reactive } from "vue";
import { useRouter } from "vue-router";
import { Upload } from "@/utils/index";
const cloneData = JSON.parse(JSON.stringify(soundJson));
const pageContent = useMyStore().customArtwork.pageContent;
let pageIndex = useMyStore().pageIndex;
let item = ref(cloneData);
const router = useRouter();
const rec = ref(null);
const wave = ref(null);
const recwave = ref(null);
const recBlob = ref(null);
const currentRate = ref(0);
const setPlayList = ref(["手动释放", "自动释放"]);
const repList = ref(["首次释放", "重复释放"]);
const timeList = ref(["立即释放", "延时释放"]);
const payIndex = ref(0);
const status = ref("lyks");
const totalTime = ref(0);
const isRelease = ref(false);

const lyImage = {
  lyks,
  lyz,
  stop,
  sf,
};
const currentActive = reactive({
  releaseSettings: 0,
  duplicate: 0,
  delay: 0,
});
const handleSoundJson = (name, index) => {
  currentActive[name] = index;
  item.value[name] = index;
};

const handleSound = () => {
  if (status.value == "lyks") {
    recOpen();
  } else if (status.value == "lyz") {
    recStop();
  } else {
    if (!isRelease.valu && status.value == "sf") {
      recPlay();
    }
  }
};
const recOpen = () => {
  //创建录音对象
  rec.value = Recorder({
    type: "mp3", //录音格式，可以换成wav等其他格式
    sampleRate: 16000, //录音的采样率，越大细节越丰富越细腻
    bitRate: 16, //录音的比特率，越大音质越好
    onProcess: (
      buffers,
      powerLevel,
      bufferDuration,
      bufferSampleRate,
      newBufferIdx,
      asyncEnd
    ) => {
      //录音实时回调，大约1秒调用12次本回调
      //可实时绘制波形，实时上传（发送）数据
      if (wave.value)
        wave.value.input(
          buffers[buffers.length - 1],
          powerLevel,
          bufferSampleRate
        );
    },
  });
  status.value = "lyz";
  //打开录音，获得权限
  rec.value.open(
    () => {
      console.log("录音已打开");
      console.log(recStart);
      recStart();
    },
    (msg, isUserNotAllow) => {
      //用户拒绝了录音权限，或者浏览器不支持录音
      console.log((isUserNotAllow ? "UserNotAllow，" : "") + "无法录音:" + msg);
    }
  );
};
const recStart = () => {
  if (!rec.value) {
    console.error("未打开录音");
    return;
  }

  rec.value.start();
  console.log("已开始录音");
};

const recStop = () => {
  if (!rec.value) {
    console.error("未打开录音");
    return;
  }
  status.value = "stop";
  rec.value.stop(
    async (blob, duration) => {
      //blob就是我们要的录音文件对象，可以上传，或者本地播放
      recBlob.value = blob;

      const data = await Upload("mp3", blob);
      item.value.url = data.url;
      console.log(item.value);
      //简单利用URL生成本地文件地址，此地址只能本地使用，比如赋值给audio.src进行播放，赋值给a.href然后a.click()进行下载（a需提供download="xxx.mp3"属性）
      var localUrl = (window.URL || webkitURL).createObjectURL(blob);

      console.log("录音成功", blob, localUrl, "时长:" + duration + "ms");
      totalTime.value = duration;

      rec.value.close(); //关闭录音，释放录音资源，当然可以不释放，后面可以连续调用start
      rec.value = null;
    },
    (err) => {
      console.error("结束录音出错：" + err);
      rec.value.close(); //关闭录音，释放录音资源，当然可以不释放，后面可以连续调用start
      rec.value = null;
    }
  );
};
const recPlay = () => {
  isRelease.value = true;
  startLoading();
  //本地播放录音试听，可以直接用URL把blob转换成本地播放地址，用audio进行播放
  var localUrl = URL.createObjectURL(recBlob.value);
  console.log(recBlob.value);
  var audio = document.createElement("audio");
  audio.controls = true;
  document.body.appendChild(audio);
  audio.style.display = "none";
  audio.src = localUrl;
  audio.play(); //这样就能播放了

  //注意不用了时需要revokeObjectURL，否则霸占内存
  setTimeout(function () {
    URL.revokeObjectURL(audio.src);
  }, 5000);
};
const clearRc = () => {
  status.value = "lyks";
  recBlob.value = null;
  currentRate.value = 0;
  totalTime.value = 0;
  item.value.url = "";
};
const subSound = () => {
  if (status.value !== "stop") {
    showToast("请先开始或暂停录音");
  } else {
    if (pageContent[pageIndex]) {
      console.log("----11");
      pageContent[pageIndex].push(item.value);
    } else {
      pageContent.push([item.value]);
    }
    router.back(-1);
  }
};

const startLoading = () => {
  // 在这里您可以触发加载操作
  // 定义加载总时间，单位毫秒
  const interval = 100; // 定义更新进度的时间间隔，单位毫秒
  const step = (100 / totalTime.value) * interval; // 计算每次更新的进度
  let currentPercentage = 0;

  const loadingInterval = setInterval(() => {
    currentPercentage += step;
    currentRate.value = Math.min(currentPercentage, 100); // 确保不超过100%

    if (currentPercentage >= 100) {
      isRelease.value = false;
      clearInterval(loadingInterval); // 加载完成后清除定时器
    }
  }, interval);
};
</script>
<template>
  <div class="sound">
    <div class="textField">
      <van-field
        input-align="center"
        rows="5"
        autosize
        type="textarea"
        placeholder="可以将想说的话写在提词板上"
      />
    </div>
    <div class="sound-title">
      <div class="left" @click="clearRc">
        <van-icon color="#8B8B8B" size="12" class="handle" name="replay" />
        重录
      </div>
      <div class="right" @click="router.back(-1)">取消</div>
    </div>

    <div class="cri-wapper" @click="handleSound">
      <van-circle
        v-model:current-rate="currentRate"
        color="#E7FF0E"
        :rate="0"
        :speed="100"
        stroke-linecap="butt"
      >
        <div class="sound-click">
          <img class="icon" :src="lyImage[status]" alt="" />
          <div style="margin-top: 4px">
            {{ (totalTime / 1000).toFixed(2) }}s
          </div>
        </div>
      </van-circle>
    </div>
    <div class="sound-bottom">
      <div class="sound-left">释放设置</div>
      <div class="sound-right">
        <div
          v-for="(item, index) in setPlayList"
          :key="index"
          :class="index == currentActive.releaseSettings ? 'active' : ''"
          @click="handleSoundJson('releaseSettings', index)"
        >
          {{ item }}
        </div>
      </div>
    </div>
    <div class="sound-bottom">
      <div class="sound-left">重复设置</div>
      <div class="sound-right">
        <div
          v-for="(item, index) in repList"
          :key="index"
          :class="index == currentActive.duplicate ? 'active' : ''"
          @click="handleSoundJson('duplicate', index)"
        >
          {{ item }}
        </div>
      </div>
    </div>
    <div class="sound-bottom">
      <div class="sound-left">释放设置</div>
      <div class="sound-right">
        <div
          v-for="(item, index) in timeList"
          :key="index"
          :class="index == currentActive.delay ? 'active' : ''"
          @click="handleSoundJson('delay', index)"
        >
          {{ item }}
        </div>
      </div>
    </div>
    <div class="btn">
      <div @click="subSound">保存</div>
    </div>
  </div>
</template>
<style lang="less" scoped>
.active {
  background: linear-gradient(90deg, #dffabc 0%, #87f4df 100%) !important;
}
.icon {
  width: 40px;
  height: 40px;
}
.sound {
  padding: 30px;
  .textField {
    height: 280px;
    background: #f8f8f8;
    border-radius: 16px;
    :deep(.van-cell) {
      background: #f8f8f8;
    }
  }
  .sound-title {
    margin-top: 56px;
    margin-bottom: 27px;
    font-size: 24px;
    display: flex;
    justify-content: space-between;
  }
  :deep(.van-circle) {
    width: 150px;
    height: 150px;
  }
  .cri-wapper {
    display: flex;
    justify-content: center;
    margin-bottom: 170px;
  }
  .sound-click {
    width: 146px;
    height: 146px;
    border-radius: 50%;
    font-size: 22px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    background: linear-gradient(90deg, #dffabc 0%, #87f4df 100%);
  }
  .sound-bottom {
    padding: 0 8px 0 20px;
    margin-bottom: 24px;
    min-height: 92px;
    background: #f8f8f8;
    border-radius: 16px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    color: #333333;
    font-size: 26px;
    .sound-right {
      display: flex;
      div {
        width: 154px;
        height: 60px;
        margin-left: 26px;
        text-align: center;
        line-height: 60px;
        background: #ededed;
        border-radius: 16px;
      }
    }
  }
  .btn {
    display: flex;
    justify-content: center;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 10px;
    div {
      width: 690px;
      height: 90px;
      text-align: center;
      font-size: 28px;
      line-height: 90px;
      background: linear-gradient(90deg, #dffabc 0%, #87f4df 100%);
      border-radius: 16px;
    }
  }
}
</style>
